﻿using System.Collections.Generic;

namespace Core
{
    public class Dict2<K1, K2, V>
        //where K1 : IEquatable<K1>
        //where K2 : IEquatable<K2>
    {
        private readonly Dictionary<K1, Dictionary<K2, V>> dict = new();
        private readonly Dictionary<K1, HashSet<K2>> missing = new();

        public bool IsMissing(K1 key1, K2 key2)
        {
            if (!missing.ContainsKey(key1))
            {
                return false;
            }

            return missing[key1].Contains(key2);
        }

        public V this[K1 key1, K2 key2]
        {
            get
            {
                if (IsMissing(key1, key2)) return default;

                if (!dict.ContainsKey(key1))
                {
                    return default;
                }
                var d = dict[key1];
                if (!d.ContainsKey(key2))
                {
                    return default;
                }
                return d[key2];
            }
            set
            {
                if (!dict.ContainsKey(key1))
                {
                    dict[key1] = new Dictionary<K2, V>();
                }
                var d = dict[key1];
                d[key2] = value;
            }
        }

        public bool Contains(K1 key1, K2 key2) => this[key1, key2] == null;

        public bool Contains(K1 key1)
        {
            return dict.ContainsKey(key1);
        }

        public void SetMiss(K1 key1, K2 key2)
        {
            if (!missing.ContainsKey(key1))
            {
                missing[key1] = new HashSet<K2>();
            }

            missing[key1].Add(key2);
        }

        public void Clear()
        {
            missing.Clear();
            var list = new List<V>();
            foreach (var pair1 in dict)
            {
                list.AddRange(pair1.Value.Values);
                foreach (var element in list)
                {
                    if (element is IDispose obj)
                    {
                        obj.Dispose();
                    }
                }
                list.Clear();
                pair1.Value.Clear();
            }
            dict.Clear();
        }
    }
}
